<template>
  <section class="json-container">
    <textarea ref="jsonPaneRef" />
  </section>
</template>
<script lang="ts">
import {
  defineComponent, onMounted, reactive, ref, watch,
} from 'vue';

import CodeMirror from 'codemirror';
import 'codemirror/addon/lint/lint';
import 'codemirror/addon/display/panel';
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/rubyblue.css';
import 'codemirror/theme/night.css';
import 'codemirror/theme/shadowfox.css';
import 'codemirror/theme/darcula.css';
import 'codemirror/theme/solarized.css';
import 'codemirror/theme/material-ocean.css';

import 'codemirror/mode/javascript/javascript';
import 'codemirror/addon/lint/json-lint';
// require('script-loader!jsonlint')

export default defineComponent({
  name: 'CodeJson',
  props: {
    modelValue: {
      type: Object,
      default: () => ({}),
    },
    /**
       * @description: 主体配置
       * 可选值：shadowfox | night | rubyblue | solarized | material-ocean
       */
    theme: {
      type: String,
      default: 'shadowfox',
    },
  },
  emits: ['changed', 'input', 'update:modelValue'],
  setup(props, { emit }) {
    const jsonPaneRef = ref();
    let jsonEditor: any = null;
    const state = reactive({
      options: {
        lineNumbers: true,
        mode: 'application/json',
        gutters: ['CodeMirror-lint-markers'],
        theme: props.theme,
        lint: false,
        selfContain: true,
      },
    });
    const initCodeMirror = () => {
      jsonEditor = (CodeMirror as any).fromTextArea(jsonPaneRef.value, state.options);
      // doc.setValue(content: string) :set the editor content
      jsonEditor.setValue(
        JSON.stringify(props.modelValue, null, 2)
      );

      jsonEditor.on('change', (cm: { getValue: () => any }) => {
        emit('changed', cm.getValue());
        emit('input', cm.getValue());
      });
      jsonEditor.addPanel = () => {
        console.log('jsonEditor.addPanel');
      };
    };
    const getValue = () => jsonEditor.getValue();
    onMounted(() => {
      initCodeMirror();
    });
    watch(
      () => props.theme,
      (theme, prevTheme) => {
        if (theme !== prevTheme) {
          jsonEditor.setOption('theme', theme);
        }
      }
    );
    return { jsonPaneRef, getValue };
  },
});
</script>
<style lang="scss" scoped>
:deep(.cm-s-shadowfox) {
  height: 100%;
}

.json-container {
  position: relative;
  height: 100%;
}
</style>
